﻿#include "SLT_rwlock.h"
#include "SL_asynFrameImp.h"

SLF_SessionTask::~SLF_SessionTask()
{
	//printf("destory SLF_SessionTask\n");
	for (auto lItem : m_eventList) {
		delete lItem;
	}
}

int SLT_setAsynFrameTimer(SLT_TIMER_HANDLE& _th, int _intervalMs, bool periodic, SLT_timerTimeOut _fun, void* _userData);
void SLF_SessionTask::setTimer(uint32_t timerID, int _intervalMs, bool periodic)
{
	auto tIter = m_timerMap.find(timerID);
	if (tIter != m_timerMap.end()) {
		return; //不能重复设置
	}
	timer_overlapped* over = new timer_overlapped();
	over->sid = m_sessid;
	over->timerID = timerID;
	over->intervalMs = _intervalMs;
	over->periodic = periodic;

	m_timerMap.insert(std::make_pair(timerID, over));
	
	SLT_setAsynFrameTimer(over->th, _intervalMs, periodic, onTimerCB, over);
}
void SLF_SessionTask::onTimerCB(SLT_timer_CallBackType _type, SLT_TIMER_HANDLE timerid, void* userData)
{
	timer_overlapped* over = (timer_overlapped*)userData;
	over->m_type = SLF_event_timer;
	over->timerCBType = _type;
	auto task = SLF_frameImp::findSession(over->sid);
	if (!task) {
		delete over;
		return ;
	}
	task->pushEvent(over);
}

void SLF_SessionTask::pushEvent(SLF_event* _pev)
{
	//事件多线程调用，如果有线程在执行，则保存后返回。如果没有线程执行，则保存事件后触发线程池执行
	m_eventListLock.lock();
	m_eventList.push_back(_pev);
	if (false == m_run) {
		m_owerFrame->postTask(m_sessid);
		m_run = true;
	}
	m_eventListLock.unlock();
}
void SLF_SessionTask::onEvent()
{
	//线程调度，连续执行
	SLF_event* pevent = nullptr;
	while (1) {
		{
			std::unique_lock<std::mutex> ul(m_eventListLock);
			if (m_eventList.empty()) {
				m_run = false;
				return;
			}
			pevent = m_eventList.front();
			m_eventList.pop_front();
		}
		if (SLF_event_start == pevent->m_type){
			//stop是多线程的。这种情况不应出现
			if (m_state == sessionState_init) {
				m_state = sessionState_start;
			}
			m_pSession->OnStart();
		} else if (SLF_event_stop == pevent->m_type) {
			if (m_state == sessionState_stoping) {
				m_pSession->OnStop();
				m_state = sessionState_stop;
				m_pSession->setTaskPtr(SLF_SessionTaskBasePtr());
				//m_pSession->m_taskPtr.reset();
				
				//解除管理，删除内部管理对象
				m_owerFrame->delSession(m_sessid);
			}
		}else if (SLF_event_timer == pevent->m_type) {
			timer_overlapped* ptimer = (timer_overlapped*)pevent;
			auto tIter = m_timerMap.find(ptimer->timerID);
			if (tIter != m_timerMap.end()) {
				//避免sessionid重复分配，遗留定时器触发错误删除
				if (ptimer->th == tIter->second->th) {
					m_timerMap.erase(ptimer->timerID);
					if (m_state == sessionState_start) {
						m_pSession->OnTimer(ptimer->timerID, ptimer->intervalMs, ptimer->periodic);
					}
				}
			}
		}
		else if (SLF_event_data == pevent->m_type) {
			if (m_state == sessionState_start) {
				SLF_event_memData* pmemData = (SLF_event_memData*)pevent;
				m_pSession->OnMsgArrive(pmemData->m_sender, pmemData->m_srcSid, pmemData->m_msgid,pmemData->m_data);
			}
		}
		else {
			printf("type error. %s", __FUNCTION__);
		}

		delete pevent;  //无论如何要走到这里
	}
}
void   SLF_SessionTask::delSelf()
{
	m_state = sessionState_stoping;
	SLF_event* pev = new SLF_event();
	pev->m_type = SLF_event_stop;
	this->pushEvent(pev);
	return;
}
bool   SLF_SessionTask::postMsg(uint32_t _SessID, int msgid, SLF_sendMemBasePtr _data)
{
	auto dstSessPtr = SLF_frameImp::findSession(_SessID);
	if (!dstSessPtr) {
		return false;
	}
	SLF_event_memData* pev = new SLF_event_memData;
	pev->m_type = SLF_event_data;
	pev->m_data = _data;
	pev->m_srcSid = m_sessid;
	pev->m_msgid = msgid;
	dstSessPtr->pushEvent(pev);
	return true;
}
////////////////////////////////  SLF_frame 全局管理  /////////////////////////////////////////////////////
//static std::mutex  g_sessionMapLock_20220124;   //使用读写锁优化
static SLT_rwlock g_sessionMapLock_20220124;
std::map<uint32_t, SLF_SessionTaskPtr>  SLF_frameImp::g_sessionMap;
SLF_SessionTaskPtr    g_sessionTaskNull;
std::mutex   SLF_frameImp::g_globalInitLock;
bool  SLF_frameImp::g_bInit = false;
std::atomic<uint32_t>   SLF_frameImp::g_sessionIDBase; //0为无效id
  
void SLF_frameImp::SLF_global_init()
{
	if (false == g_bInit) {
		g_globalInitLock.lock();
		if (false == g_bInit) {
			g_bInit = true;
			//g_sessionIDBase = rand(); 
			g_sessionIDBase = 0;  //测试阶段使用
		}
		g_globalInitLock.unlock();
	}
}
uint32_t  SLF_frameImp::getSessionID()
{
	//获得空闲id
	while (1) {
		uint32_t sID = g_sessionIDBase++;
		if (sID == 0) {
			sID = g_sessionIDBase++;
		}
		SLF_SessionTaskPtr fsid = findSession(sID);
		if (! fsid) {
			return sID;
		}
	}
	return 0;
}
SLF_SessionTaskPtr SLF_frameImp::findSession(uint32_t _sid)
{
	//std::lock_guard<std::mutex>  ul(g_sessionMapLock_20220124);
	SLT_autoRWLock al(&g_sessionMapLock_20220124,SLT_autoRWLock::lock_read);
	auto fiter = g_sessionMap.find(_sid);
	if (fiter != g_sessionMap.end()) {
		return fiter->second;
	}
	return g_sessionTaskNull;
}
void SLF_frameImp::delSession(uint32_t _sid)
{
	//std::unique_lock<std::mutex>  ul(g_sessionMapLock_20220124);
	SLT_autoRWLock al(&g_sessionMapLock_20220124, SLT_autoRWLock::lock_write);
	g_sessionMap.erase(_sid);
}
//int SLF_frameImp::postEvent(uint32_t _SessID, SLF_event* _ev)
//{
//	auto task = findSession(_SessID);
//	if (!task) {
//		delete _ev;
//		return -1;
//	}
//	task->pushEvent(_ev);
//	return 0;
//}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void SLF_frameImp::frameThreadTask::onRun()
{
	//线程池执行一个task
	auto task = SLF_frameImp::findSession(m_sessID);
	if (!task) {
		return;
	}
	task->onEvent(); //任务执行后自动删除
}
////////////////////////////////  SLF_frameImp  /////////////////////////////////////////////////////
int SLF_frameImp::SLF_init(int _threadNum)
{
	SLF_global_init();
	return m_threadPool.init(_threadNum);
}
int SLF_frameImp::SLF_addSession(const SLF_SessionBasePtr &_psession)
{
	if (_psession->getSessID() != 0) {
		return -1;  //重复
	}

	//std::shared_ptr<SLF_SessionTask> ptask = std::make_shared<SLF_SessionTask>();
	SLF_SessionTaskPtr ptask(new SLF_SessionTask());
	if (!ptask) {
		return -2;
	}
	//绑定关系
	ptask->m_owerFrame = this;
	ptask->m_pSession = _psession;
	ptask->m_sessid = getSessionID();
	//_psession->m_taskPtr = std::static_pointer_cast<SLF_SessionTaskBase>(ptask);
	_psession->setTaskPtr(SLF_SessionTaskBasePtr(ptask.get()));

	//g_sessionMapLock_20220124.lock();
	g_sessionMapLock_20220124.writeLock();
	g_sessionMap.insert(std::make_pair(ptask->m_sessid, ptask));
	g_sessionMapLock_20220124.unWriteLock();
	//g_sessionMapLock_20220124.unlock();

	SLF_event* pev = new SLF_event();
	pev->m_type = SLF_event_start;
	ptask->pushEvent(pev);
	return 0;
}
void SLF_frameImp::SLF_delSession(uint32_t _sessId)
{
	auto sessTaskPtr = findSession(_sessId);
	if (sessTaskPtr) {
		sessTaskPtr->delSelf();
	}
}
bool SLF_frameImp::SLF_postMsg(uint32_t _SessID, int msgid, uint32_t _srcID,const SLF_sendMemBasePtr &_data)
{
	auto dstSessPtr = findSession(_SessID);
	if (!dstSessPtr) {
		return false;
	}

	SLF_event_memData* pev = new SLF_event_memData;
	pev->m_type = SLF_event_data;
	pev->m_data = _data;
	pev->m_srcSid = _srcID;
	pev->m_msgid = msgid;
	dstSessPtr->pushEvent(pev);
	return true;
}
bool  SLF_frameImp::SLF_pushEvent(uint32_t _SessID, int msgid, uint32_t _srcID, SLF_sendMemBasePtr& _data,const SLF_senderPtr& _senderPtr)
{
	auto dstSessPtr = findSession(_SessID);
	if (!dstSessPtr) {
		return false;
	}

	SLF_event_memData* pev = new SLF_event_memData;
	pev->m_type = SLF_event_data;
	pev->m_data = _data;
	pev->m_srcSid = _srcID;
	pev->m_msgid = msgid;
	pev->m_sender = _senderPtr;
	dstSessPtr->pushEvent(pev);
	return true;
}
bool  SLF_frameImp::SLF_postMsg2(uint32_t _SessID, int msgid, uint32_t _srcID, SLF_sendMemBasePtr &_data,const SLF_senderPtr& _senderPtr)
{
	if (_senderPtr) {
		return _senderPtr->SLF_postMsg(_SessID, msgid, _srcID, _data);
	}
	return false;
}
void  SLF_frameImp::postTask(uint32_t _sessID)
{
	//触发线程执行
	frameThreadTask *ptask = new frameThreadTask();
	if (!ptask) {
		return;
	}
	ptask->m_sessID = _sessID;
	m_threadPool.post_task(ptask);
}